using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Sucrose.Base
{

    public class Course
    {
        #region instanceVars

        private int      id;
        private Term     term;
        private String   courseNumber;
        private String   courseName;
        private String   url;
        private String   description;
        private UserRole userRole;
        private double   passRangeStart = -1;
        private double[] letterGrades;
        private double   gradePercent;
        private String   gradeLetter;
        private double   estimatedGradePercent;
        private String   estimatedGradeLetter;
        private GradeConversion conversionMethod;

        private List<CourseItem>        allItems;
        private List<DownloadableItem>  downloadableItems = new List<DownloadableItem>();
        private List<TaskItem>          taskItems = new List<TaskItem>();

        #endregion

        #region basicProperties

        public int Id
        {
            get
            {
                return id;
            }
            set
            {
                this.id = value;
            }
        }

        public Term Term
        {
            get
            {
                return term;
            }
            set
            {
                this.term = value;
            }
        }

        public String CourseNumber
        {
            get
            {
                return courseNumber;
            }
            set
            {
                this.courseNumber = value;
            }
        }

        public String CourseName
        {
            get
            {
                return courseName;
            }
            set
            {
                this.courseName = value;
            }
        }

        public String Url
        {
            get
            {
                return url;
            }
            set
            {
                this.url = value;
            }
        }

        public String Description
        {
            get
            {
                return description;
            }
            set
            {
                this.description = value;
            }
        }

        public UserRole UserRole
        {
            get
            {
                return userRole;
            }
            set
            {
                this.userRole = value;
            }
        }

        public double PassRangeStart
        {
            get
            {
                return passRangeStart;
            }
            set
            {
                this.passRangeStart = value;
            }
        }

        public double[] LetterGrades
        {
            get
            {
                return letterGrades;
            }
            set
            {
                this.letterGrades = value;
            }
        }

        public double GradePercent
        {
            get
            {
                return gradePercent;
            }
            set
            {
                this.gradePercent = value;
            }
        }

        public String GradeLetter
        {
            get
            {
                return gradeLetter;
            }
            set
            {
                this.gradeLetter = value;
            }
        }

        public double EstimatedGradePercent
        {
            get
            {
                return estimatedGradePercent;
            }
            set
            {
                this.estimatedGradePercent = value;
            }
        }

        public String EstimatedGradeLetter
        {
            get
            {
                return estimatedGradeLetter;
            }
            set
            {
                this.estimatedGradeLetter = value;
            }
        }

        public GradeConversion ConversionMethod
        {
            get
            {
                return this.conversionMethod;
            }
            set
            {
                this.conversionMethod = value;
            }
        }

        public List<CourseItem> AllItems
        {
            get
            {
                return this.allItems;
            }
            set
            {
                this.allItems = value;
            }
        }

        public List<DownloadableItem> DownloadableItems
        {
            get
            {
                return this.downloadableItems;
            }
            set
            {
                this.downloadableItems = value;
            }
        }

        public List<TaskItem> TaskItems
        {
            get
            {
                return this.taskItems;
            }
            set
            {
                this.taskItems = value;
            }
        }

        #endregion

        #region constructors

        /// <summary>
        /// Creates a Course object
        /// </summary>
        public Course()
        {
        }

        #endregion

        #region methods

        /// <summary>
        /// Converts a string representing UserRole to a value in the UserRole enumeration
        /// </summary>
        /// <param name="role">The string representation from the LMS</param>
        /// <returns>a value in the UserRole enumeration</returns>
        public static UserRole StringRoleToUserRole(String role)
        {
            //student, ta, admin, professor
            switch (role)
            {
                case "student":
                    return UserRole.Student;
                case "ta":
                    return UserRole.Ta;
                case "admin":
                    return UserRole.Admin;
                case "professor":
                    return UserRole.Professor;
                default:
                    return UserRole.Student;
            }
        }

        /// <summary>
        /// Converts a string representing GradeCoversion to a value in the GradeConversion enumeration
        /// </summary>
        /// <param name="conversion">The string representation from the LMS</param>
        /// <returns>a value in the GradeConversion enumeration</returns>
        public static GradeConversion StringConversionToGradeConversion(String conversion)
        {
            switch (conversion)
            {
                case "none":
                    return GradeConversion.None;
                case "letters":
                    return GradeConversion.Letters;
                case "pass_fail":
                    return GradeConversion.PassFail;
                default:
                    return GradeConversion.Letters;
            }
        }

        /// <summary>
        /// Converts a percentage to a letter grade for this course
        /// </summary>
        /// <param name="percentage">Percentage to convert</param>
        /// <returns>Letter grade</returns>
        public String PercentageToGrade(double percentage)
        {
            percentage *= 100;

            if (this.conversionMethod == GradeConversion.PassFail)
            {
                if (percentage > this.passRangeStart)
                    return "Passing";
                else
                    return "Failing";
            }
            else if (this.conversionMethod == GradeConversion.Letters)
            {
                if (percentage >= this.letterGrades[0])
                    return "A";
                else if (percentage >= this.letterGrades[1])
                    return "A-";
                else if (percentage >= this.letterGrades[2])
                    return "B+";
                else if (percentage >= this.letterGrades[3])
                    return "B";
                else if (percentage >= this.letterGrades[4])
                    return "B-";
                else if (percentage >= this.letterGrades[5])
                    return "C+";
                else if (percentage >= this.letterGrades[6])
                    return "C";
                else if (percentage >= this.letterGrades[7])
                    return "C-";
                else if (percentage >= this.letterGrades[8])
                    return "D+";
                else if (percentage >= this.letterGrades[9])
                    return "D";
                else if (percentage >= this.letterGrades[10])
                    return "D-";
                else
                    return "F";
            }
            else
            {
                return "No grade conversion method is defined in this class";
            }

        }

        #endregion
    }
}
